Muchas veces tenemos la necesidad de mantener copias de nuestros archivos digitales y existe una forma sencilla y descentralizada usando [Syncthing](https://syncthing.net).

![Syncthing cluster](/static/imgs/posts/varios/syncthing/syncthing-rep1.jpg)

Este post muestra una forma de instalación y configuración sencilla de Syncthing para tener varias copias de nuestros archivos en equipos propios.

## Sobre Syncthing

Syncthing es un programa de sincronización de archivos que no requiere un servidor centralizado y usa una estrategia **p2p** donde los archivos se sincronizan entre los participantes directamente. En Syncthing los dispositivos participantes forman un *cluster* donde cada dispositivo tiene una o mas carpetas que sincroniza con los demás dispositivos, mediante [protocolos específicos](https://docs.syncthing.net/specs/index.html) estos se descubren, intercambian información sobre sus carpetas y sincronizan sus archivos.

Syncthing funciona para varios sistemas operativos entre ellos, Windows, GNU/Linux, Android, etc. y cuenta con una cómoda interfaz web de configuración.

## Esquema propuesto

![Esquema syncthing 1](/static/imgs/posts/varios/syncthing/syncthing-esquema-1.jpg)

Para esta demostración sincronizaremos 3 equipos: una laptop, una pc de escritorio y un servidor remoto. La laptop y la pc de escritorio están dentro una red de área local (LAN) y el servidor remoto en internet y tiene un dominio de ejemplo servidor.algo.net.

## Instalación y arranque inicial

Syncthing se puede instalar en diferentes sistemas operativos como Windows y android, en un sistema basado en debian se puede instalar en cada equipo con:

    :::bash
    sudo apt install syncthing

Cada dispositivo en el *cluster* syncthing tiene un **device id** o identificador único que se genera a partir de certificados digitales, syncthing los puede generar y para este ejemplo usaremos el directorio de guardado por defecto.

    :::bash
    # crea un directorio para syncthing
    mkdir ~/.config/syncthing
    
    # genera un nuevo device id y los certificados correspondientes
    syncthing -generate=~/.config/syncthing
	
	# para comprobar el device-id
	syncthing -device-id

Dentro de la carpeta `~/.config/syncthing` también se generará un archivo de configuración `config.xml` con configuraciones iniciales. En principio tenía la intención de editar este archivo y agregar las configuraciones ahí directamente, pero tuve dificultades y decidí usar la interfaz gráfica que es muy versátil y fácil de manejar.

Para iniciar syncthing con exponiendo una interfaz gráfica en el navegador usaremos el siguiente comando en cada equipo:

    :::bash
    # en la laptop
    syncthing -no-browser -home="~/.config/syncthing/" -verbose
    
    # en la pc de escritorio
    syncthing -no-browser -home="~/.config/syncthing" -verbose \
	  -gui-address="0.0.0.0:8384"
    
    # en el servidor remoto
    syncthing -no-browser -home="~/.config/syncthing" -verbose \
	  -gui-address="0.0.0.0:8384"

La opción `-gui-address="0.0.0.0:8384"` inicia una aplicación para atender a peticiones desde un navegador web desde un equipo en cualquier red por eso `0.0.0.0`. No es seguro mantener este servidor web escuchando a cualquier equipo ya que cualquier persona podría ingresar, por ello solo mantendremos este acceso para configurar y cuando terminemos de configurar **quitaremos el acceso irrestricto**.

Ahora podemos acceder a cada panel de administración de syncthing en cada equipo, en la laptop lo haríamos desde un navegador web ingresando a http://localhost:8384, en la pc de escritorio sería http://ip-pc-escritorio:8384 y en el servidor remoto asumiendo que esta disponible en el dominio servidor.algo.net desde http://servidor.algo.net:8384.

## Configuración desde la interfaz gráfica

La interfaz desde el navegador web debería ser:

![gui1](/static/imgs/posts/varios/syncthing/gui1.jpg)

Ingresaremos a `Acciones > Ajustes > General` ahí podemos ajustar el nombre del equipo para mejor entendimiento.

![gui2](/static/imgs/posts/varios/syncthing/gui2.jpg)
![gui3](/static/imgs/posts/varios/syncthing/gui3.jpg)

Haremos lo mismo con cada dispositivo en este caso nombrando lpatop, pc-escritorio y servidor.

### Enlazando

Syncthing por defecto define una carpeta y una ruta donde se guardan las carpetas sincronizadas y la llama `default folder`, se puede cambiar estas rutas y nombres y también agregar mas carpetas pero para esta demostración no modificaremos nada de eso.

Para enlazar dos dispositivos es necesario que ambos conozcan el `device id` del otro y así puedan conectarse. Para ver este valor en la interfaz ingresamos a `Acciones > Mostrar ID`.

![gui4](/static/imgs/posts/varios/syncthing/gui4.jpg)
![gui5](/static/imgs/posts/varios/syncthing/gui5.jpg)

Ahora copiamos el ID que se muestra y usaremos el botón `Agregar nuevo dispositivo` en los demás equipos para pegar este ID. Podemos marcar las opciones *Auto Acept* y *Default Folder* para aceptar contenido del nuevo dispositivo y que carpetas propias compartir con este.

![gui6](/static/imgs/posts/varios/syncthing/gui6.jpg)
![gui7](/static/imgs/posts/varios/syncthing/gui7.jpg)

Es importante agregar los dispositivos de esta manera de forma mutua, es decir si agregamos el ID de la laptop en la pc de escritorio, también debemos agregar el ID de la pc de escritorio en la laptop o no se podrá establecer conexión.

Una vez enlazados, en la interfaz gráfica debería mostrarse el nuevo dispositivo agregado.

### Probando la compartición de archivos

Ahora probaremos la sincronización, en el `Default Folder` de la laptop que en mi caso es `/home/usuario/Sync` copiaremos algunos archivos, unos segundos después los demás equipos deberían detectar que ha habido un cambio en esta carpeta y empezarán a sincronizar sus contenidos. Cuando esto pase en la interfaz gráfica se mostrará el progreso de la sincronización.

Lo mismo pasará cuando por ejemplo agreguemos contenido en el `Default Folder` del servidor, los demás dispositivos en el *cluster* detectarán este cambio y en la interfaz gráfica se mostrará el resultado de la sincronización.

![gui8](/static/imgs/posts/varios/syncthing/gui8.jpg)

### Haciendo los cambios permanentes

He notado que para que se apliquen los cambios parece ser necesario una vez configurado y probado todo **reiniciar** syncthing desde la interfaz gráfica (`Acciones > Reiniciar`) y estos cambios se escribirán en el archivo `config.xml` en cada dispositivo.

### Otras configuraciones

Es importante notar que syncthing tiene muchas opciones de configuración, por ejemplo podríamos definir que el equipo servidor sea solamente de respaldo y que los cambios en su carpeta no se propaguen a los demás equipos del cluster. Hay muchas otras opciones como por ejemplo definir una contraseña de acceso a la interfaz gráfica, limitar el ancho de banda para sincronización, excluir carpetas, definir direcciones IP fijas por ejemplo con `tcp://ip-equipo`, etc. Para mayor información se puede consultar la [documentación oficial](https://docs.syncthing.net/) de syncthing o revisar sus manuales con `man syncthing`, `man syncthing-config` y otros.

## Configurando Inicio automático

En la [documentación oficial](https://docs.syncthing.net/users/autostart.html#linux) hay ejemplos de como configurar el auto arranque. Si vas a hacer este paso recuerda primero detener cualquier proceso syncthing y no usar la opción `-gui-address="0.0.0.0:8384"` a menos que configures buenos credenciales de acceso.

Para este caso usaré `systemd` y creando el archivo `/etc/systemd/system/syncthing@usuario.service` se puede iniciar syncthing para que inicie con las configuraciones guardadas en el archivo `~/.config/syncthing/config.xml`.

    :::conf
    [Unit]
    Description=Syncthing - Open Source Continuous File Synchronization for usuario
    Documentation=man:syncthing(1)
    After=network.target

    [Service]
    User=usuario
    ExecStart=/usr/bin/syncthing -home=/home/usuario/.config/syncthing -no-browser -no-restart -logflags=0
    Restart=on-failure
    RestartSec=5
    SuccessExitStatus=3 4
    RestartForceExitStatus=3 4

    # Hardening
    ProtectSystem=full
    PrivateTmp=true
    SystemCallArchitectures=native
    MemoryDenyWriteExecute=true
    NoNewPrivileges=true

    [Install]
    WantedBy=multi-user.target
	
Una vez creado el archivo es necesario decirle a systemd que habilite este como nuevo servicio de inicio con

    :::bash
    systemctl enable syncthing@myuser.service
    systemctl start syncthing@myuser.service
	
El mismo procedimiento se puede hacer en la pc de escritorio y el servidor.

**AYUDA:** Si fallas al editar el archivo `/etc/systemd/system/syncthing@usuario.service` y haces modificaciones para corregir, recuerda que debes usar `sudo systemctl daemon-reload` y `systemctl restart syncthing@myuser.service` para que los cambios tengan efecto.

## Conclusión

Como vimos Syncthing es un programa muy útil y de fácil configuración para tener carpetas sincronizadas entre varios equipos a nuestro control, esta en constante desarrollo, tiene buen soporte de su comunidad y podemos aprovecharlo para tener un servicio de respaldo como alternativa libre a los servicios centralizados como dropbox, google y otros.

Espero este pequeño tutorial te haya servido :)
